/**
 * Licensed under the MIT License
 *
 * Copyright (c) 2010 Benoit Saint-Maxent
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */
package marcel.controller.command {

	/**
	 * IMacroCommand handles a stack of sub-commands and triggers their execution in a FIFO order when "execute" is called.
	 * A given ICommand instance can't be pushed twice in the stack.
	 * 
	 * @author Benoit Saint-Maxent
	 */
	public interface IMacroCommand extends ICommand {
		/**
		 * Pushes the passed-in sub-command at the end of the stack
		 * @param 	command	The ICommand instance to push in the stack
		 * @return	true 	if the sub-command has been added to the stack successfully
		 */
		function addSubCommand(command : ICommand) : Boolean;
		
		/**
		 * Removes the passed-in sub-command from the stack
		 * @param 	command	The ICommand instance to remove from the stack
		 * @return	true 	if the sub-command has been removed from the stack successfully
		 */
		function removeSubCommand(command : ICommand) : Boolean;
		
		/**
		 * Removes the sub-command registered in the stack at the particular passed-in index.
		 * @param 	index	Stack index where the sub-command should be removed
		 * @return	true 	if the sub-command has been removed from the stack successfully
		 */
		function removeSubCommandAt(index : uint) : Boolean;
		
		/**
		 * Removes all sub-commands from the stack
		 */
		function removeAllSubCommands() : void;
		
		/**
		 * Adds the passed-in sub-command to add in the stack before the passed-in sub-command to search.
		 * @param 	commandToSearch	The ICommand instance to search in the stack
		 * @param 	commandToAdd	The ICommand instance to add in the stack
		 * @return	true 			if the sub-command has been added to the stack successfully
		 */
		function addSubCommandBefore(commandToSearch : ICommand, commandToAdd : ICommand) : Boolean;
		
		/**
		 * Adds the passed-in sub-command to add in the stack after the passed-in sub-command to search.
		 * @param 	commandToSearch	The ICommand instance to search in the stack
		 * @param	commandToAdd	The ICommand instance to add in the stack
		 * @return	true 			if the sub-command has been added to the stack successfully
		 */
		function addSubCommandAfter(commandToSearch : ICommand, commandToAdd : ICommand) : Boolean;
		
		/**
		 * Adds the passed-in sub-command to add in the stack at the particular passed-in index.
		 * @param 	index	Stack index where the sub-command should be added
		 * @param 	command	The ICommand instance to add in the stack
		 * @return	true 	if the sub-command has been added to the stack successfully
		 */
		function addSubCommandAt(index : uint, command : ICommand) : Boolean;
		
		/**
		 * Gives the number of sub-commands int the stack
		 * @return	the number of sub-commands int the stack
		 */
		function get numSubCommands() : uint;
	}
}
